#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int BOARDSIZE[2]{ 5,8};//棋盘格每行每列角点个数
//!每次运行完毕需关闭终端，否则下次运行图像不显示
int main() {
    cv::Mat image ;
	vector<Point2f> img_corner_points;//保存每张图检测到的角点
    cv::Mat img_gray;
    vector<vector<Point2f>> images_points;//保存所有角点
    vector<vector<Point3f>> objpoints_img;//保存棋盘格上角点的三维坐标
	vector<Point3f> obj_world_pts;//三维世界坐标
    	vector<String> images_path;//创建容器存放读取图像路径

	string image_path = "/home/zajun/code/贴片机/biao_ding/棋盘格/未裁剪/右.jpg";//待处理图路径	F:/Works/C++/openCV/opencv study/Revise/Revise/Project1/
	glob(image_path, images_path);//读取指定文件夹下图像
    	//转世界坐标系
	for (int i = 0; i < BOARDSIZE[1]; i++)
	{
		for (int j = 0; j < BOARDSIZE[0]; j++)
		{
			obj_world_pts.push_back(Point3f(j, i, 0));
		}
	}
    for (int i = 0; i < images_path.size(); i++)
	{
            image = imread(images_path[i]);
            cv::cvtColor(image, img_gray, cv::COLOR_BGRA2GRAY);
            //检测角点
            //!棋盘格需精密灰度打印，不能像图1一样带有白色皱痕(但是图2有褶皱也能正确检测角点，应考虑是角度和光线原因)
            bool patternFound = findChessboardCorners(img_gray, Size(BOARDSIZE[0], BOARDSIZE[1]),
            img_corner_points,
            CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE);
            cout<<"pattern = "<<patternFound<<endl;
            if (patternFound) {
            cv::cornerSubPix(img_gray, img_corner_points, cv::Size(11, 11), cv::Size(-1, -1),
                    cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.1));
            for (int i = 0; i < img_corner_points.size(); i++) {
            cv::circle(image, img_corner_points[i], 5, cv::Scalar(0, 0, 255), 2);
            }
            objpoints_img.push_back(obj_world_pts);//从世界坐标系到相机坐标系
            images_points.push_back(img_corner_points);
            namedWindow("Detected Corners",WINDOW_NORMAL);
            cv::imshow("Detected Corners", image);
        }
    }
/*
	计算内参和畸变系数等
	*/
	Mat cameraMatrix, distCoeffs, R, T;//内参矩阵，畸变系数，旋转量，偏移量
	calibrateCamera(objpoints_img, images_points, img_gray.size(),
	cameraMatrix, distCoeffs, R, T);

	cout << "cameraMatrix:" << endl;
	cout << cameraMatrix << endl;

	cout << "*****************************" << endl;
	cout << "distCoeffs:" << endl;
	cout << distCoeffs << endl;
	cout << "*****************************" << endl;

	cout << "Rotation vector:" << endl;
	cout << R << endl;

	cout << "*****************************" << endl;
	cout << "Translation vector:" << endl;
	cout << T << endl;

///*
	//畸变图像校准
	//*/
	Mat src, dst;
	src = imread("/home/zajun/code/贴片机/biao_ding/image_read/测试2.jpg");  //F:/Works/C++/openCV/opencv study/Revise/image/2.jpg
	undistort(src, dst, cameraMatrix, distCoeffs);

	char texts[] = "image_undst";
	char *dst_output = texts;
	//char *dst_output = "image_dst";
     namedWindow(dst_output,WINDOW_NORMAL);
	imshow(dst_output, dst);
    namedWindow("image_dst",WINDOW_NORMAL);
	imshow("image_dst", src);
    cout << "size="<<image.size;
    //waitKey(0);//等待用户按下按键，窗口关闭；没有该代码，窗口会闪退;想要截图应该使用下面的代码，否则直接退出了
    // 等待按键
    while (true)
    {
        int key = waitKey(10);
        if (key == 27) break; // 按下ESC键退出
        if (key == 'q') break; // 按下q键退出
    }
    return 0;
}

//    版权声明：本文为博主原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接和本声明。
                        
// 原文链接：https://blog.csdn.net/weixin_42734533/article/details/110201793